package com.hzdf.oosplugin

import android.app.Application
import android.util.Log
import com.alibaba.fastjson.JSONObject
import com.amazonaws.ClientConfiguration
import com.amazonaws.Protocol
import com.amazonaws.auth.BasicAWSCredentials
import com.amazonaws.regions.Region
import com.amazonaws.regions.Regions
import com.amazonaws.services.s3.AmazonS3Client
import com.amazonaws.services.s3.S3ClientOptions
import com.amazonaws.services.s3.model.ObjectMetadata
import com.amazonaws.services.s3.model.PutObjectRequest
import io.dcloud.feature.uniapp.UniAppHookProxy
import io.dcloud.feature.uniapp.annotation.UniJSMethod
import io.dcloud.feature.uniapp.bridge.UniJSCallback
import io.dcloud.feature.uniapp.common.UniModule
import java.io.File
import java.util.Date

/**
 * @author ZhangShuang
 * @date 2025-08-18 17:09
 * @description
 */
class OOSPlugin : UniModule(), UniAppHookProxy {

    companion object {
        private const val TAG = "OOSPlugin"
        private var s3Client: AmazonS3Client? = null
    }

    override fun onCreate(application: Application) {
        Log.d(TAG, "OOSPlugin Application onCreate")
    }

    override fun onSubProcessCreate(application: Application) {
        Log.d(TAG, "OOSPlugin Application onSubProcessCreate")
    }

    @UniJSMethod(uiThread = true)
    fun initSDK(options: JSONObject, callback: UniJSCallback) {
        try {
            val endpoint = options.getString("endpoint")
                ?: throw IllegalArgumentException("Endpoint is required")
            val accessKey = options.getString("accessKey")
                ?: throw IllegalArgumentException("AccessKey is required")
            val secretKey = options.getString("secretKey")
                ?: throw IllegalArgumentException("SecretKey is required")
            val region = options.getString("region") ?: "cn-north-1"

            // 1. 创建认证凭证
            val credentials = BasicAWSCredentials(accessKey, secretKey)

            // 2. 创建客户端配置
            val clientConfig = ClientConfiguration().apply {
                connectionTimeout = 30_000
                socketTimeout = 60_000
                maxConnections = 50
                protocol = Protocol.HTTP
                signerOverride = "S3SignerType" // OOS特殊要求
            }

            // 3. 初始化S3客户端
            s3Client = AmazonS3Client(credentials, clientConfig).apply {
                // 4. 设置Region
                setRegion(Region.getRegion(Regions.fromName(region)))

                // 5. 设置端点
                setEndpoint(endpoint)

                // 6. 创建并配置S3选项 - 使用正确方式
                val s3Options = S3ClientOptions().apply {
                    withPathStyleAccess(true) // 开启路径样式访问
                    withPayloadSigningEnabled(true)
                }

                // 7. 应用配置
                setS3ClientOptions(s3Options)
            }

            Log.i(TAG, "OOS SDK 6.2.0 initialized successfully")
            callback.invoke(mapOf(
                "code" to 200,
                "message" to "OOS SDK initialized"
            ))
        } catch (e: Exception) {
            Log.e(TAG, "Initialization failed", e)
            callback.invoke(mapOf(
                "code" to 500,
                "message" to "Initialization failed: ${e.message}",
                "detail" to e.stackTraceToString()
            ))
        }
    }

    @UniJSMethod(uiThread = false)
    fun uploadFile(params: JSONObject, callback: UniJSCallback) {
        if (s3Client == null) {
            callback.invoke(mapOf(
                "code" to 401,
                "message" to "SDK not initialized. Call initSDK first."
            ))
            return
        }

        val bucketName = params.getString("bucket")
            ?: return callback.invoke(mapOf("code" to 400, "message" to "Bucket is required"))
        val objectKey = params.getString("key")
            ?: return callback.invoke(mapOf("code" to 400, "message" to "Key is required"))
        val filePath = params.getString("filePath")
            ?: return callback.invoke(mapOf("code" to 400, "message" to "File path is required"))

        try {
            val file = File(filePath)
            if (!file.exists()) {
                return callback.invoke(mapOf(
                    "code" to 404,
                    "message" to "File not found: $filePath"
                ))
            }

            // 创建元数据
            var mMetadata = ObjectMetadata().apply {
                contentLength = file.length()
                contentType = params.getString("contentType") ?: "binary/octet-stream"
                addUserMetadata("x-oos-uniapp", "true")
            }

            // 创建上传请求
            val request = PutObjectRequest(
                bucketName,
                objectKey,
                file
            ).apply {
                metadata = mMetadata
            }

            // 执行上传
            val result = s3Client!!.putObject(request)

            callback.invoke(mapOf(
                "code" to 200,
                "etag" to result.eTag,
                "versionId" to result.versionId,
                "size" to file.length(),
                "lastModified" to Date().time
            ))

        } catch (e: Exception) {
            Log.e(TAG, "Upload failed", e)
            callback.invoke(mapOf(
                "code" to 500,
                "message" to "Upload failed: ${e.message}",
                "detail" to e.stackTraceToString()
            ))
        }
    }
}